home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / preccx / prccx240.lha / ccx.h < prev    next >
C/C++ Source or Header  |  1993-05-09  |  17KB  |  510 lines

  1.  
  2. # ifndef CC_H
  3. # define CC_H
  4.  
  5. # ifdef __MSDOS__
  6. # define p_memleft()  coreleft()
  7. # else
  8. # define p_memleft()  32000
  9. # endif
  10.  
  11. # define CHAR char
  12. typedef CHAR *characters;
  13. # define CHARS characters
  14.  
  15.  
  16. /* standard clib */                     /* p_gets is undefined, so set  */
  17. # include <stdio.h>                     /* it to gets, which is.        */
  18. # define p_gets(x) gets(x)
  19. # define p_calloc(x,y)  calloc((long)(x),(long)(y))
  20. # define p_free(x)    free((VOID *)(x))
  21. # include <stdarg.h>
  22. # include <string.h>
  23. # include <setjmp.h>
  24. # include <values.h>
  25.  
  26.  
  27.  
  28. /* default defs */
  29. # ifndef VALUE
  30. # define VALUE char *        /* make sure you define VALUE !! */
  31. # endif
  32. # ifndef TOKEN
  33. # define TOKEN char            /* and TOKEN, if not int and char */
  34. # endif
  35. # ifndef PARAM
  36. # define PARAM long            /* VALUE=synthetic, PARAM=inherited */
  37. # endif
  38. # ifndef MAXPROGRAMSIZE
  39. # define MAXPROGRAMSIZE 4096        /* 20K (chars) is often too big in DOS*/
  40. # endif                    /* but this is prop. to line length */
  41. # ifndef READBUFFERSIZE
  42. # define READBUFFERSIZE 2048        /* ditto */
  43. # endif                    /* because this IS the line length */
  44. # ifndef STACKSIZE
  45. # define STACKSIZE 4096            /* Very difficult to overun 2K ! */
  46. # endif                    /* because this is nesting depth */
  47.  
  48.                                /* msdos defns */
  49. # ifndef CONTEXTSTACKSIZE
  50. # define CONTEXTSTACKSIZE 1024
  51. # endif
  52. # ifndef C_STACKSIZE
  53. # define C_STACKSIZE 0x7FFF
  54. # endif
  55.  
  56. # define MAXARGS 8         /* number of params catered for */
  57.                             /* DON'T change it! */
  58.  
  59. # define P_STOP (PARAM)(MAXINT-3)
  60.  
  61. extern  int        yytchar;            /* the last thing yylex saw     */
  62. extern  int        yylineno;        /* line count */
  63. /* I'll put in the decls for the yystuff here, in case they're needed */
  64. extern  int        yylen;
  65. extern  int        yylex();
  66. extern  char      *yylloc;
  67. extern  VALUE      yylval;
  68.  
  69.  
  70. /* local defs */
  71. # define OPCODE char
  72. # define VOID void
  73.  
  74. /* typedefs */
  75. typedef PARAM status;            /* STATUS is returned by a PARSER */
  76. # define STATUS status
  77.  
  78. typedef STATUS  PARSER();        /* PARSER returns a STATUS */
  79. # define TOPARSER *(PARSER*)
  80. typedef VOID    ACTION();        /* VALUE stack manipulation */
  81. typedef int boolean;            /* BOOLEAN is returned by a PREDICATE */
  82. # define BOOLEAN boolean
  83. typedef BOOLEAN PREDICATE();    /* PREDICATE returns a BOOLEAN */
  84.  
  85. typedef struct {            /* an INSTRUCTION consists of ... */
  86.     OPCODE  opcode;            /* an OPCODE as opcode and ... */
  87.     union {                /* an ACTION or  ... */
  88.             ACTION  *act;    /* a literal as operand. */
  89.             TOKEN   tok;        /* The opcode selects the */
  90.         VALUE   val;
  91.         PARAM   par;
  92.         } operand;             /* interpretation of the operand. */
  93. }       instruction;
  94. # define INSTRUCTION instruction
  95. typedef union {                /* The VALUE stack actually contains */
  96.            VALUE val;        /* STACKVALUES, which may be either */
  97.         TOKEN tok;        /* VALUEs or TOKENs. TOKENs are */
  98.         PARAM par;        /* ... */
  99.         } stackvalue;            /* pushed when literals are hit. */
  100. # define STACKVALUE stackvalue
  101. typedef struct{             /* all the info required for a REWIND */
  102.         TOKEN     *pstr;
  103.         STACKVALUE *value;
  104.         int pc;
  105.         int lineno;
  106.         /* INSTRUCTION instr;*/ /* will introduce for optimization */
  107.         } FRAME;
  108. typedef struct {
  109. int     readbuffersize,      /* READBUFFERSIZE */
  110.         maxprogramsize,      /* MAXPROGRAMSIZE */
  111.         stacksize,           /* STACKSIZE */
  112.         contextstacksize;    /* CONTEXTSTACKSIZE */
  113. }       PRECC_DATA;
  114.  
  115. typedef INSTRUCTION  *PROGRAM;       /* a PROGRAM is a list of INSTRUCTIONs*/
  116.  
  117. /* instruction destructors and constructors */
  118. # define Action(x) ((x).operand.act)
  119. # define Token(x)  ((x).operand.tok)
  120. # define Param(x)  ((x).operand.par)
  121. # define Opcode(x) ((x).opcode)
  122. # define Value(x)  ((x).operand.val)
  123.  
  124. /* status macros */
  125. # define BADSTATUS(x)  (!(x))        /* BADSTATUS(x) is a PREDICATE */
  126. # define GOODSTATUS(x) (x)        /* as is GOODSTATUS(x) */
  127. # define OK(x) ((x)||0xFFFF)
  128. # define KO(x) 0
  129. # define SUCCESS OK(1)
  130. # define FAILURE KO(0)
  131.  
  132. /* input stream manipulations */
  133.                     /* MARK has to be first line in a */
  134.                     /* routine. 'string' is a reserved */
  135.                     /* local variable, as is 'count'. */
  136.                     /* The MARK sets string and count to */
  137.                     /* the current parse point and pc. */
  138.  
  139. #define MARK {\
  140. fsave(p_frame);\
  141. fpush(p_frame);\
  142. }
  143.  
  144.                     /* REWIND resets the parse point and */
  145.                     /* to the MARK at the head of the fn.*/
  146.                     /* provided that a new line hasn't   */
  147.                     /* already been read, in which case  */
  148.                     /* just go back as far as possible */
  149.  
  150. #define REWIND {\
  151. fpop(p_frame);\
  152. frestore(p_frame);\
  153. }
  154.                     /* MOVEON budges the high-water mark */
  155.                     /* maxp up to the current parse pt. */
  156.  
  157. /* 
  158.  * maxp+1 is the first address I have not yet written into. The TOKEN
  159.  * space should be occupied by a 0. maxp is the last position  I have
  160.  * written into.
  161.  *
  162.  * pstr is the current TOKEN position. Notice that I am going to have to
  163.  * read one TOKEN into *pstr to start up?
  164.  *
  165.  * We start with pstr=maxp=&buffer, and *buffer=first token.
  166.  */
  167.  
  168. #define MOVEON if(++pstr>maxp){  /* this next space not written into yet*/\
  169.                     *pstr=(TOKEN)yylex();\
  170.                     lvbuff[pstr-buffer]=yylval;\
  171.                     maxp=pstr;\
  172.                 }
  173.  
  174. /* RELEASE destroys the frame */
  175.  
  176. # define RELEASE fpop(p_frame)
  177.  
  178. /* the secret parse string and stacks */
  179. extern TOKEN     *pstr;            /* parsed stream */
  180. extern TOKEN     *maxp;            /* maximal parse point in stream */
  181. extern TOKEN     *buffer;      /* where the pstr points to */
  182. extern TOKEN     *yybuffer;        /* points to the buffer */
  183. extern VALUE     *lvbuff; /* corresponding yylvals */
  184. extern VALUE     *plval;        /* and pointer */
  185. extern INSTRUCTION *program;
  186. extern int pc;                     /* program counter - counts up from 0 */
  187. extern int passcount;           /* number of cuts */
  188. extern STACKVALUE  *stack;       /* the evaluation stack - either VALUEs
  189.                        or TOKENs */
  190. extern STACKVALUE  *value;        /* top of evaluation stack */
  191. extern FRAME     *fstack;       /* top of frame stack ... */
  192. extern FRAME     *fptr;         /* and pointer. */
  193. extern FRAME      p_frame;      /* a frame cache */
  194. extern INSTRUCTION instr;        /* single instruction cache */
  195. extern int call_mode;            /* 0 for auto-calling convention, 1=manual */
  196. extern int optimize;            /* 1 = flying program optimization */
  197. extern jmp_buf jmpb;            /* environment */
  198. extern int p_argc;              /* main() arg count */
  199. extern char **p_argv;           /* main() arg vector*/
  200. extern PRECC_DATA precc_data;
  201. extern int msdos;
  202. extern PARSER *p_entry;
  203. extern int     p_enargs;
  204. extern PARAM   p_eargv[MAXARGS];
  205.  
  206.  
  207. /* opcodes */
  208. # define INCR   5            /* increment value stack */
  209. # define PARM   4            /* parameter to a function call */
  210. # define FUNC   3            /* That's got an ACTION operand */
  211. # define EXIT   2
  212. # define CNST   1            /* That's got a VALUE operand. */
  213. # define NOP    0            /* Saves time. */
  214.  
  215. /* program stack manipulation */
  216. #define push(x) {if(pc>=precc_data.maxprogramsize-1){\
  217.                  fprintf(stderr,"precc: program stack overflow (%d)\n",pc);\
  218.                  exit(1);\
  219.                  }\
  220.                  program[pc++]=(x);\
  221.                 }
  222. # define pull(n) (pc-=(n))
  223. # define pop(x)  (x=program[--pc])
  224. # define ppeek(x) (pc>0?x=program[pc-1]:((x).opcode=EXIT,(x)))
  225. # define ppoke(x) {if(pc>0)program[pc-1]=(x);}
  226.  
  227. /* load and unlaod the current instruction */
  228. #define getinstruction(n,x)   {Opcode(instr)=(n);Action(instr)=(x);}
  229. #define pushinstruction(n,x)  {getinstruction(n,x);push(instr);}
  230. #define gettoken(x)           {Opcode(instr)=(CNST);Token(instr)=(TOKEN)(x);}
  231. #define getparam(x)           {Opcode(instr)=(PARM);Param(instr)=(PARAM)(x);}
  232. #define getmanip(x)           {Opcode(instr)=(INCR);Param(instr)=(PARAM)(x);}
  233. #define getvalue(x)           {Opcode(instr)=(CNST);Value(instr)=(VALUE)(x);}
  234. #define pushTOKEN(x)          {gettoken(x);push(instr);}
  235. #define pushPARAM(x)          {getparam(x);push(instr);}
  236. #define pushVALUE(x)          {getvalue(x);push(instr);}
  237. #define pushACTION(x)         pushinstruction(FUNC,(x))
  238. #define pushEXIT              pushinstruction(EXIT,0)
  239. /* don't allow extra stack manips if call_mode=1 */
  240. /* and let's try some on-the-fly optimisation    */
  241. #define pushMANIP(x)          if(!call_mode){\
  242.                                if(optimize&&(Opcode(ppeek(instr))==(INCR))){\
  243.                                    Param(instr) += (PARAM)(x);\
  244.                                    ppoke(instr);\
  245.                                } else{\
  246.                                    getmanip(x);\
  247.                                    push(instr);\
  248.                                }\
  249.                               }
  250. # define pushINCR               pushMANIP(1)
  251. # define pushDECR               pushMANIP(-1)
  252. # define pushNOP               pushinstruction(NOP,0)
  253.  
  254. /* evaluation stack manipulation */
  255. # define pushvalue(x) ((*value++).val)=(x)
  256. # define pushparam(x) ((*value++).par)=(x)
  257. # define pushtoken(x) ((*value++).val)=(VALUE)(x)
  258. # define popvalue(x)  (x=(*--value).val)
  259. # define poptoken(x)  (x=(TOKEN)(*--value).val)
  260. # define popparam(x)  (x=(*--value).par)
  261. # define pullvalue(n) &((value-=(n))->val)
  262. # define pullparam(n) &((value-=(n))->par)
  263. # define pulltoken(n) &(TOKEN)((value-=(n))->val))
  264. /*
  265. # define pullvalue(n) &stack[(int)(value-=(n))-(int)stack].val
  266. # define pullparam(n) &stack[(int)(value-=(n))-(int)stack].par
  267. # define pulltoken(n) &stack[(int)(value-=(n))-(int)stack].tok
  268. */
  269.  
  270. /* frame stack manipulation */
  271. # define fpush(x) (*fptr++=(x))
  272. # define fpop(x)  (x=*--fptr)
  273. # define fpull(n) (fptr-=(n))
  274. # define fsave(x) \
  275. x.pstr=pstr;\
  276. x.value=value;\
  277. x.pc=pc;\
  278. x.lineno=passcount
  279. /*;\ ppeek(x.instr)*/
  280. # define frestore(x) \
  281. pstr=(x.lineno==passcount)?x.pstr:(btk_error(),buffer);\
  282. pc=x.pc;\
  283. value=x.value
  284. /*; ppoke(x.instr)*/
  285.  
  286.  
  287.  
  288. /* multi-argument function call */
  289.  
  290. /* I have to use int's in the param list because of possible promotion */
  291.  
  292. # define CALL(p,m,a)  {\
  293.     m=va_arg(ap,int);\
  294.     a=(PARAM*)ap; /* very NON-PORTABLE, but it's fast */\
  295.     ap=(va_list)&a[m];\
  296.     m++;\
  297.     switch(m-1) {\
  298.     case 0: p();break;\
  299.     case 1: p(a[0]);break;\
  300.     case 2: p(a[0],a[1]);break;\
  301.     case 3: p(a[0],a[1],a[2]);break;\
  302.     case 4: p(a[0],a[1],a[2],a[3]);break;\
  303.     case 5: p(a[0],a[1],a[2],a[3],a[4]);break;\
  304.     case 6: p(a[0],a[1],a[2],a[3],a[4],a[5]);break;\
  305.     case 7: p(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);break;\
  306.     case 8: p(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);break;\
  307.     default: printf("error: too many (%d) args in CALL\n",m-1); exit(100);\
  308.     }\
  309. }
  310.  
  311.  
  312. # ifndef DOS
  313. /* SUNUNIX versions */
  314. # define setvalue(n)  pullvalue(call_mode?(n)-1:0);value[-1].val
  315. # define settoken(n)  pullvalue(call_mode?(n)-1:0);(TOKEN)(value[-1].val)
  316. # define refvalue(n)  (value[(n)-2].val)
  317. # define reftoken(n)  (TOKEN)(value[(n)-2].val)
  318. # define refpar(n)    (value[(n)-2].par)
  319. /*
  320. # define refvalue(n) stack[(int)value+(n)-1-(int)stack].val
  321. # define reftoken(n) stack[(int)value+(n)-1-(int)stack].tok
  322. # define refpar(n) stack[(int)value+(n)-2-(int)stack].par
  323. */
  324. # else
  325. /* BORLAND versions */
  326. # define setvalue(n)  ((pullvalue(call_mode?(n)-1:0))[-1].val)
  327. # define settoken(n)  (TOKEN)((pullvalue(call_mode?(n)-1:0))[-1].val)
  328. # define refvalue(n)  (value[(n)-2].val)
  329. # define reftoken(n)  (TOKEN)(value[(n)-2].val)
  330. # define refpar(n)    (value[(n)-2].par)
  331. # endif
  332.  
  333. /* program-interpreter */
  334.     /* in engine.c */
  335. extern int p_evaluate();
  336.  
  337. /* read and run parser, interpret resulting program */
  338.     /* in engine.c */
  339. extern ACTION p_run;
  340.  
  341. /* parsers without actions */
  342.     /* defined in cc.c */
  343. extern PARSER p_andparse0;
  344. extern PARSER p_orparse0;
  345. extern PARSER p_many0;
  346. extern PARSER p_iter0;
  347. extern PARSER p_some0;
  348. extern PARSER p_option0;
  349. extern PARSER p_range0;
  350. extern PARSER p_hidden0;
  351.  
  352.     /* but here are macros */
  353. # define p_andparse0(x,y) p_andparse0n(x,(char)0,y,(char)0)
  354. # define  p_orparse0(x,y) p_orparse0n(x,(char)0,y,(char)0)
  355. # define     p_many0(x) p_many0n(x,(char)0)
  356. # define   p_iter0(n,x) p_iter0n(n,x,(char)0)
  357. # define     p_some0(x) p_some0n(x,(char)0)
  358. # define   p_option0(x) p_option0n(x,(char)0)
  359. # define    p_range0(x) p_range0n(x,(char)0)
  360. # define   p_hidden0(x) p_hidden0n(x,(char)0)
  361.  
  362.     /* defined in common.c */
  363. extern PARSER p_nothing0;
  364. extern PARSER p_anything0;
  365. extern PARSER p_first0;
  366. extern PARSER p_last0;
  367. extern PARSER p_exactly0;
  368. extern PARSER p_notexactly0;
  369. extern PARSER p_attach0;
  370. extern PARSER p_uniq0;
  371.  
  372. /* parsers with actions attached */
  373.     /* in cc.c */
  374. extern PARSER p_attach;
  375. extern PARSER p_prepend;
  376.     /* in common.c */
  377. extern PARSER p_andparse;
  378. extern PARSER p_orparse;
  379. extern PARSER p_nothing;
  380. extern PARSER p_option;
  381. extern PARSER p_many;
  382. extern PARSER p_iter;
  383. extern PARSER p_some;
  384. extern PARSER p_anything;
  385. extern PARSER p_first;
  386. extern PARSER p_last;
  387. extern PARSER p_exactly;
  388. extern PARSER p_notexactly;
  389. extern PARSER p_range;
  390.  
  391.     /* but replaced by macros here */
  392.  
  393. # define ATTACH(p,f) if(GOODSTATUS(p))pushACTION(f)
  394. # define p_attach(x,y) p_attach0n(x,(char)0,y,(char)0)
  395. # define p_prepend(x,y) p_prepend0n(x,(char)0,y,(char)0)
  396.  
  397. # define p_andparse(p,q,f) ATTACH(p_andparse0(p,q),f)
  398. # define p_orparse(p,q,f) ATTACH(p_orparse0(p,q),f)
  399. # define p_many(p,f) ATTACH(p_many0(p),f)
  400. # define p_iter(n,p,f) ATTACH(p_iter0(n,p),f)
  401. # define p_some(p,f) ATTACH(p_some0(p),f)
  402. # define p_option(p,f) ATTACH(p_option0(p),f)
  403. # define p_nothing(f) ATTACH(p_nothing0(),f)
  404. # define p_anything(f) ATTACH(p_anything0(),f)
  405. # define p_first(f) ATTACH(p_first0(),f)
  406. # define p_last(f) ATTACH(p_last0(),f)
  407. # define p_exactly(f) ATTACH(p_exactly0(),f)
  408. # define p_notexactly(f) ATTACH(p_notexactly0(),f)
  409. # define p_range(p,f) ATTACH(p_range0(p),f)
  410.  
  411. /*
  412. */
  413.  
  414. /* parsers taking a variable number of arguments */
  415. extern STATUS p_andparse0n(PARSER *, ...);
  416. extern STATUS p_orparse0n(PARSER *, ...);
  417. extern STATUS p_option0n(PARSER *, ...);
  418. extern STATUS p_hidden0n(PARSER *, ...);
  419. extern STATUS p_many0n(PARSER *, ...);
  420. extern STATUS p_iter0n(int, PARSER *, ...);
  421. extern STATUS p_some0n(PARSER *, ...);
  422. extern STATUS p_uniq0n(PARSER *, ...);
  423. extern STATUS p_attach0n(PARSER *, ...);
  424. extern STATUS p_prepend0n(ACTION *, ...);
  425. extern STATUS p_range0n(PREDICATE *, ...);
  426. extern PARSER p_test0;
  427.  
  428. /* actions*/
  429.     /* in common.c */
  430. extern ACTION p_nop;
  431.  
  432. /* aux */
  433. extern char *p_scpy();
  434. extern void exit(int);
  435.     /* (in on_error.c) */
  436. extern ACTION zer_error;
  437. extern ACTION bad_error;
  438. extern ACTION btk_error;
  439. extern ACTION precc_begin;
  440. extern ACTION precc_end;
  441.     /* lexer (in yystuff.c)*/
  442. extern int yylex();
  443.     /* in engine.c */
  444. extern PREDICATE  mygets;
  445.  
  446. # ifndef BEGIN
  447. # define BEGIN
  448. # endif
  449. # ifndef END
  450. # define END
  451. # endif
  452.  
  453. # ifndef BAD_ERROR    /* failed parse marked at deepest pt */
  454. # define BAD_ERROR(x) fprintf(stderr,"(line %d) error:\
  455.  parse failed near ..<>%s\n",yylineno,maxp);yylloc=NULL;
  456. # endif
  457. # ifndef ZER_ERROR    /* incomplete parse shows remainder */
  458. # define ZER_ERROR(x) fprintf(stderr,"(line %d) error:\
  459.  parse terminated early near ..<>%s\n",yylineno,maxp);yylloc=NULL;
  460. # endif
  461. # ifndef BTK_ERROR  /* backtracking across a new line boundary */
  462. # define BTK_ERROR(x) if (!p_entry) fprintf(stderr,"(line %d) error:\
  463.  parse backtracked across cut from point near <>%s\n\
  464. ",yylineno,maxp);yylloc=NULL;longjmp(jmpb,1);
  465. # endif
  466.  
  467. # ifndef ON_ERROR    /* default error mechanism */
  468. # define ON_ERROR(x) switch(x){\
  469. case 1:BAD_ERROR(1);break;\
  470. case 0:ZER_ERROR(0);break;\
  471. case -1:BTK_ERROR(-1);break;\
  472. }
  473. # endif
  474.  
  475. #define MAIN(x) \
  476. int main(argc,argv)\
  477. int argc; char **argv;\
  478. {\
  479. PARSER x;ACTION p_run;\
  480. void precc_free(), precc_call();\
  481. if (msdos) brk(C_STACKSIZE); /* set the C stack to 32K */\
  482. p_argc=argc;p_argv=argv;\
  483. precc_call();\
  484. atexit(precc_free);\
  485. p_run (x);\
  486. return 0;\
  487. }\
  488.  VOID  zer_error(){ON_ERROR(0);}\
  489.  VOID  bad_error(){ON_ERROR(1);}\
  490.  VOID  btk_error(){ON_ERROR(-1);}\
  491.  VOID  precc_begin(){BEGIN;}\
  492.  VOID  precc_end(){END;}\
  493.  void  precc_call(){ACTION p_creat_data;\
  494.  precc_data.readbuffersize=READBUFFERSIZE;\
  495.  precc_data.maxprogramsize=MAXPROGRAMSIZE;\
  496.  precc_data.stacksize=STACKSIZE;\
  497.  precc_data.contextstacksize=CONTEXTSTACKSIZE;\
  498.  p_creat_data();}\
  499.  void  precc_free(){ACTION p_destr_data;p_destr_data();}
  500.  
  501.  
  502.  
  503.  
  504. # define V(n) refvalue(n)    /*n'th argument*/
  505. # define T(n) reftoken(n)    /*n'th argument*/
  506. # define VV(n) setvalue(n)    /*result from n args*/
  507. # define TT(n) settoken(n)    /*result from n args*/
  508.  
  509. # endif
  510.